package org.boot.easyapi.util.jdbc;

import org.boot.easyapi.util.jdbc.kingbase.KingBaseAnalyzeUtil;
import org.boot.easyapi.util.jdbc.mysql.MysqlAnalyzeUtil;
import org.boot.easyapi.enums.db.DbEnum;
import org.boot.easyapi.util.StrUtil;
import org.boot.easyapi.pojo.db.DbDTO;
import org.boot.easyapi.pojo.db.TableDTO;
import org.boot.easyapi.util.spring.SpringUtil;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.DatabaseMetaData;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



/**
 * JDBC 操作工具类
 */
public class JdbcUtil {


    /*******************************************获取数据库信息***********************************************/
    public static DbDTO getDb(JdbcTemplate jdbcTemplate){
        DbDTO dbInfo = jdbcTemplate.execute((ConnectionCallback<DbDTO>) con -> {
            DatabaseMetaData metaData = con.getMetaData();
            DbDTO info = new DbDTO();
            // 核心元数据
            info.setDbType(metaData.getDatabaseProductName());  // 如 MySQL/Oracle
            info.setDbVersion(metaData.getDatabaseProductVersion());
            info.setDbDriver(metaData.getDriverVersion());
            info.setDbUrl(metaData.getURL());
            info.setDbUserName(metaData.getUserName());
            info.setSchema(extractCurrentSchema(metaData.getURL()));
            info.setDbName(extractDatabaseName(metaData.getURL()));
            return info;
        });
        return dbInfo;
    }


    /*******************************************获取所有表结构***********************************************/
    public static List<TableDTO> getTable(JdbcTemplate jdbcTemplate, String tableName){
        DbDTO db = getDb(jdbcTemplate);
        if(db.getDbType().toLowerCase().contains("mysql")){
            return MysqlAnalyzeUtil.analyzeTableBuild(jdbcTemplate, tableName);
        }else if(db.getDbType().toLowerCase().contains("kingbase") || db.getDbType().toLowerCase().contains("postgresql")){  //kingbase、postgresql
            String finalSchema = extractCurrentSchema(db.getDbUrl());
            return KingBaseAnalyzeUtil.analyzeKingBaseES(jdbcTemplate, tableName, finalSchema);
        }
        return MysqlAnalyzeUtil.analyzeTableBuild(jdbcTemplate, tableName);
    }

    public static List<TableDTO> getTable(String tableName){
        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
        DbDTO db = getDb(jdbcTemplate);
        if(db.getDbType().toLowerCase().contains("mysql")){
            return MysqlAnalyzeUtil.analyzeTableBuild(jdbcTemplate, tableName);
        }else if(db.getDbType().toLowerCase().contains("kingbase") || db.getDbType().toLowerCase().contains("postgresql")){  //kingbase、postgresql
            String finalSchema = extractCurrentSchema(db.getDbUrl());
            return KingBaseAnalyzeUtil.analyzeKingBaseES(jdbcTemplate, tableName, finalSchema);
        }
        return MysqlAnalyzeUtil.analyzeTableBuild(jdbcTemplate, tableName);
    }






    /*******************************************解析所有表结构***********************************************/
    public static Map<String, List<TableDTO>> getMysqlTables(JdbcTemplate jdbcTemplate){
        return MysqlAnalyzeUtil.analyzeDb(jdbcTemplate);
    }




    /******************************************工具方法****************************************/

    public static DbEnum checkDbType(){
        DbDTO db = getDb(SpringUtil.getBean(JdbcTemplate.class));
        String dbType = db.getDbType();
        if(db.getDbType().toLowerCase().contains("mysql")){
            return DbEnum.MYSQL;
        }else if(db.getDbType().toLowerCase().contains("kingbase") || db.getDbType().toLowerCase().contains("postgresql")){  //kingbase、postgresql
            return DbEnum.POSTGRESQL;
        }
        return DbEnum.MYSQL;
    }

    /**
     * 从数据库连接字符串中提取数据库名
     * @param connectionString 数据库连接字符串
     * @return 数据库名
     */
    public static String extractDatabaseName(String connectionString) {
            if (StrUtil.isEmpty(connectionString)) return  null;
        // 去掉可能存在的末尾参数
        String trimmedConnection = connectionString.trim();
        int questionMarkIndex = trimmedConnection.indexOf('?');
        if (questionMarkIndex != -1) {
            trimmedConnection = trimmedConnection.substring(0, questionMarkIndex);
        }
        // 提取数据库名
        int lastSlashIndex = trimmedConnection.lastIndexOf('/');
        if (lastSlashIndex != -1 && lastSlashIndex < trimmedConnection.length() - 1) {
            return trimmedConnection.substring(lastSlashIndex + 1);
        }
        return  null;
    }


    /**
     * 从数据库连接字符串中提取模式（currentSchema）信息
     * @param connectionString 数据库连接字符串
     * @return 模式（currentSchema）信息
     */
    public static String extractCurrentSchema(String connectionString) {
        if (connectionString == null || connectionString.isEmpty()) return  null;
        // 正则表达式匹配 currentSchema 参数
        String regex = "currentSchema=([^&]*)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(connectionString);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return  null;
    }

}
